/*
Copyright 2010 Dmitry Barashev

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
 */
package net.barashev.seclub.io;

import java.util.Arrays;

public abstract class FixedLengthRecordBlock<T, M extends DataMarshaller<T>> {
    private final byte[] bytes;
    private final M marshaller;
    private final int blockSize;

    public FixedLengthRecordBlock(byte[] bytes, int blockSize, M marshaller) {
        this.bytes = bytes;
        this.blockSize = blockSize;
        this.marshaller = marshaller;

    }

    public int getRecordCount() {
        return this.blockSize / this.marshaller.getDataItemSize();
    }

    private int getRecordOffset(int idx) {
        return getBlockStartOffset() + idx * this.marshaller.getDataItemSize();
    }
    public T get(int idx) {
        int recordOffset = getRecordOffset(idx);
        byte[] recordBytes = copyRange(this.bytes, recordOffset, this.marshaller.getDataItemSize());
        return this.marshaller.parseFrom(recordBytes);
    }

    void set(int idx, T value) {
        byte[] bytes = this.marshaller.write(value);
        System.arraycopy(bytes, 0, this.bytes, getRecordOffset(idx), this.marshaller.getDataItemSize());
    }

    protected abstract int getBlockStartOffset();

    private static byte[] copyRange(byte[] source, int offset, int length) {
        byte[] result = new byte[length];
        System.arraycopy(source, offset, result, 0, length);
        return result;
    }
}
